package com.sorcery.coupon.service;

import com.sorcery.coupon.constant.RoleEnum;
import com.sorcery.coupon.dao.PathRepository;
import com.sorcery.coupon.dao.RolePathMappingRepository;
import com.sorcery.coupon.dao.RoleRepository;
import com.sorcery.coupon.dao.UserRoleMappingRepository;
import com.sorcery.coupon.entity.Path;
import com.sorcery.coupon.entity.Role;
import com.sorcery.coupon.entity.RolePathMapping;
import com.sorcery.coupon.entity.UserRoleMapping;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Optional;

/**
 * 权限校验功能服务接口实现
 *
 * @author jinglv
 * @date 2024/4/30 15:53
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class PermissionService {
    private final PathRepository pathRepository;
    private final RoleRepository roleRepository;
    private final UserRoleMappingRepository userRoleMappingRepository;
    private final RolePathMappingRepository rolePathMappingRepository;

    /**
     * 用户访问接口权限校验
     *
     * @param userId     用户id
     * @param uri        访问uri
     * @param httpMethod 请求类型
     * @return true/false
     */
    public Boolean checkPermission(Long userId, String uri, String httpMethod) {
        // 如果用户角色映射表找不到记录，直接返回false
        UserRoleMapping userRoleMapping = userRoleMappingRepository.findByUserId(userId);
        if (null == userRoleMapping) {
            log.error("userId not exist is UserRoleMapping: {}", userId);
            return false;
        }
        // 如果找不到对应的角色记录，直接返回false
        Optional<Role> role = roleRepository.findById(userRoleMapping.getRoleId());
        if (!role.isPresent()) {
            log.error("roleId not exist in Role:{}", userRoleMapping.getRoleId());
            return false;
        }
        // 如果用户角色是超级管理员，直接返回true
        if (role.get().getRoleTag().equals(RoleEnum.SUPER_ADMIN.name())) {
            return true;
        }
        // 如果路径没有注册（忽略了），直接返回true
        Path path = pathRepository.findByPathPatternAndHttpMethod(uri, httpMethod);
        if (null == path) {
            return true;
        }
        RolePathMapping rolePathMapping = rolePathMappingRepository.findByRoleIdAndPathId(role.get().getId(), path.getId());
        return rolePathMapping != null;
    }
}
